spcas v0.01 documentation
Author: byuu
Release Date: 08/01/2004
Intro:
spcas is a cross-assembler for the Sony
SPC-700 processor, which is used in the SFC/SNES as a sound processor.
Features:
Supports all 256 opcodes
Supports labels and sublabels
Brackets:
Brackets, { and }, may be used anywhere within the code to help organize
it structurally, they are converted to whitespace and then removed by
the assembler.
Labels and Sublabels:
A label is used to represent a position in code,
and allows one to code without having to constantly update branches
and jumps/calls. A label can be used in most opcodes, on either side
of the opcode, but I have only added explicit support for opcodes that
might actually use this functionality. Those being: branches, jumps, calls.
Labels can contain A-Za-z0-9_. They must end with : or ()
A sublabel is used to declare labels within labels that will share its
address space only, and can contain the same characters as a label, but
must start with a period. A sublabel must not end with a : or ().
Here's an example:
proc1:
nop
.l1
bra .l1
proc2:
nop
.l1
bra .l1
Sublabels allow you to reuse redundantly named labels such as loop, end,
etc. without causing duplicate label conflicts. A new sublabel group is
started immediately after a label is declared automatically.
: Separator
The : is used to allow multiple opcodes on the same line. It requires
a space before and after usage, to differentiate it from the : used
to end labels.
Example: mov a,$00 : nop
This is useful for making each line define an action, rather than just
an opcode. Very useful when combined with { } to indicate a structural
flow of assembly code, rather than a straight descending list. But you're
free to code however you like.
Math:
Math is supported in all opcodes, and all functions, however, it has
one major variation from traditional math. It does not resolve math
in order if symbols, it instead resolves from left to right, and also
does not use parinthesis to denote order. An example:
Standard Math:
mov a,5+6*2 ;=17
Left-to-right Math:
mov a,6*2+5 ;=17
mov a,5+6*2 ;=22
I do apologize for this limitation, it was just far easier and faster
to implement left-to-right math, and for an assembler, I haven't really
come across anything that could not be represented in left-to-right math.
To use left-to-right math, just reorder your multiplication and division
to the start, and use addition and subtraction at the end. The math system
supports the following commands:
+ : Addition
- : Subtraction
* : Multiplication
/ : Division
<< : Left-shift ( x<
>> : Right-shift ( x >> y formula: x = x / 2^y )
& : Bitwise AND
| : Bitwise OR
^ : Bitwise XOR (Note: Not exponentials)
~ : Bitwise NOT
Math also works with labels. Example:
mov a,label2-label1+2
Additional Commands:
incbin:
The incbin command will let you insert a binary file into the output
binary image. Usage:
incbin filename.bin
fill / fillbyte:
fillbyte will allow you to select the byte used by fill, and fill can be
used to fill x number of bytes with the fillbyte. Example:
fillbyte $ff : fill 16
This will write 16 $ff's to the file, and will increment the pc counter
automatically.
pad / padbyte:
This is identical to fill / fillbyte, except that pad takes an offset
instead of a number of bytes to write. It will continue writing bytes
until the offset is reached. Example:
org $0200 : padbyte $ff : pad $0210
This will write 16 $ff's to the file, and will increment the pc counter
automatically.
db / dw / dl / dd:
These are used to write binary data to the file.
db - 8-bit byte write mode
dw - 16-bit word write mode
dl - 24-bit long write mode
dd - 32-bit dword write mode
Multiple arguments can be passed to these commands by means of a comma.
Example:
db $01,$02,$03,$04
dw $0001,$0002,$0003,$0004
This command also accepts labels and text as arguments, example:
dw label : db "This is a test",$00
Text is written using the ascii table. There is no table support, as
this is, after all, a sound processor.
org:
org is used to set the file position. It will not update the base location,
you must set the base location manually after using org! If you seek
to a position past the current position in the file, the null space will
be filled with 00's. You are free to seek backwards into an existing file,
if need be.
loadpc / savepc / warnpc:
These are used for spanning multiple files, and warning when you exceed
certain ranges. loadpc will load in a file, which is an index of pc
addresses. You can specify just loadpc filename.xpc, or you can specify
an index into this file, such as loadpc filename.xpc,2. If no index is
specified, 0 is assumed. It will seek to index * 2, and read in two bytes,
then set pc to this value. savepc works the same way, except it will save
the pc value to specified index location. You can use these two in
conjunction to assemble multiple files without having to space the code
apart due to fears of the first files code size growing too large and
cutting into the second files code, then the second file eating the first
files code. warnpc just takes an address, it will compare the current pc
to the address you specified, if the current address is >= the address
specified, it will give you an error. Useful if you want your code to
be between x and y, and data to be between y and z. You can make sure
your code isn't so large that it exceeds y this way.
base:
base is used to set the pc position, which is used to calculate label
positions. You could be at file offset 0, and set the base to $200,
then, even though you are assembling to $0 in the binary file, it will
be treated as though you were assembling to $200 in regards to
branch/jump/call instructions. This is useful for spc-700 assembly,
as the file location is generally not where you load the code into
its RAM at.
Additional Notes:
As I have just begun learning spc700 assembly, I am not too sure what
commands would be useful for this processor, and I believe the org/base
solution I used presently will quickly prove inferior. I do plan on
improving this in due time, as I get used to programming for the system.
So expect that to change in future releases... I hope to add defines, and
+/- labels to this assembler in the future, as well. But I don't plan
on adding incsrc or macros, as spc700 assembly routines for entire games
are usually under 4kbytes in binary form. Time will tell, however...
Opcodes:
Please see the included test.asm file for a list of opcodes. I also plan
to add useful psuedo-opcodes in the future.